Repository navigation
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #504 +/- ##
==========================================
+ Coverage 77.35% 77.47% +0.12%
==========================================
Files 160 162 +2
Lines 16836 16891 +55
Branches 4845 4860 +15
==========================================
+ Hits 13023 13086 +63
+ Misses 3813 3805 -8
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
…dge cases Only JSX text decodes entities, so literals are scanned as written. The clean string-literal fixture never compared a pair, so it is replaced, and fixtures now pin the nearest-text rule inside elements and the skip over comments and empty literals. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The listener teardown test reads ExpoIapModule.kt for the cleanup call, and the endConnection fix changed that line to guard on the stored handles. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The JS source-text check can no longer tell endConnection from OnDestroy, and the no-provider test runs without handles, so nothing covered the listener removal in endConnection. The new Robolectric test runs it with a provider and stored handles and checks each listener is removed once. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Fixtures pin that a literal inside an element keeps its entity as written, that the first text is found through nested elements, and that the scan recurses in the right direction. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…hase once A purchase built in code writes a blank storeId, so finishing it failed with "Invalid store identity" and the purchase was never acknowledged. The native finish paths now stamp the connected provider's identity when the input has none, and keep an explicit identity untouched. On Horizon the provider's restore already notifies the purchase listeners, and Godot's own loop signalled every owned purchase again. Listener emissions are now dropped while the provider restore runs. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…lists React Native iOS sent the purchase JSON for every finish, so a purchase that carries only an id no longer finished by lookup, and a malformed transaction id read as success. It now sends the JSON only when the purchase carries a store identity and rejects a malformed id again. An init failure that is a canonical error keeps its code instead of becoming init-connection. KMP and MAUI on iOS now treat an empty subscription id list as no filter, as they did before the native calls took the list. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…flavors With a provider platform flavor and openiapStore/openiapProvider set, assemblePlayDebug failed with a conflict against the play flavor. The properties now select the provider flavor only, through the same provider validation as the plain path. The version-less error also names the artifact the build really links. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…se MAUI ids The Expo plugin gave one message for reserved ids, malformed ids and missing coordinates, and the fix it named could not work for the first two. Each case now has its own message. MAUI lowercases a community id before matching, as Gradle, Expo, Godot and the doctor do. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ol in version errors A cancelled requestPurchase (a SwiftUI task ending) was wrapped and delivered as a purchase-error event, and CancellationError never reached the caller. It is now rethrown as is, as are the other operations with the same catch shape. A Client Protocol mismatch reused the core-version messages. Kotlin and Swift now say "Client Protocol" with both versions and the fix. The unused public ProviderBehaviors.officialCapabilities is no longer generated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The release gates did not list openiap-core, the Kotlin conformance artifact or the Swift OpenIapConformance sources, so a change to only those needed no release card. The parity audit still looked for a removed conformance directory and passed with conformance on the published classpath. Both now check the current layout. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The React Native, Expo and Apple conformance tests checked only that the store is not unknown. They now check storeId, including a community provider. New registry tests fail when the pass rule, the scope check, the 90-day window or the tier rule is weakened. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…cription changes React Native, Expo and Flutter now run the provider's Android restore, which on Horizon delivers each owned purchase to the listeners. Expo and Flutter pass the provider's error code through. KMP's Store enum gains UNKNOWN, and Flutter, KMP and MAUI on iOS check StoreKit's active flag for id-filtered calls. The AI reference no longer says the Expo flags are removed in 6.0.0. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Follows the architecture note that says which suites assert the provider profile. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…nce README version The card now covers React Native in the error-code and iOS subscription notes, names each SDK's own restore surface, and discloses that a cancelled Apple task throws CancellationError without an error event. The restore page names Amazon's PurchaseUpdates and Godot's per-store signal, and the isActive note matches the code. The conformance README coordinate is pinned to the suite version, and the registry notes say to keep the previous suite major's profile through the maintenance window. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The restore page said every SDK runs the provider's restore first, which is not true for KMP. It now names React Native, Expo, Flutter and MAUI. The card uses the real listener names, mentions Godot's restore, and limits the cancellation note to requestPurchase and the operations that rethrow it. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
On main the GDScript restore never reached the plugin's native restore on Android, so restoring signalled nothing. Wiring it to the provider's restore also reached a loop that signalled every owned purchase on every store. The native restore now runs the provider's restore with listener emissions dropped, queries the owned purchases, and emits no signal. AARs rebuilt and digests updated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Godot's restore signals nothing and its Android failures carry the provider's code. The restore page names KMP's provider builds, the card splits its long bullets and calls the iOS flag OpenIAP's own, and the isActive intro matches the code. The registry note says a major's profile stays while any entry cites it, and the Expo restore comment describes the provider restore. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…limit Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…he result API Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…sions only on Horizon Restoring before connecting reported service-error where main reported not-prepared. The restore gate closed on every store, but only the Horizon restore notifies purchase listeners, so on Play and Amazon it could drop a genuine purchase update that arrived during the restore. It now closes only for Horizon. AARs rebuilt and digests updated. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
braces has no patched release (GHSA-vfj7-8cjw-p6xm). The six dependency graphs return to upstream braces 3.0.3 instead of a single-maintainer fork, and each lock gets a scoped, justified exception that expires on 2026-10-30. The node-forge exceptions that would have expired on 2026-10-09 are renewed to the same date. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Eight advisories (compression, joi, source-map-js, @fastify/busboy, proxy-addr, smol-toml, graphql-tools executor-legacy-ws and utils 12) are fixed by in-place lock edits. sprintf-js has no fix and the graphql-codegen chain still pins utils 11, so those two get expiring exceptions. The image-size reasons now name the real blocker (Metro pins ^1.0.2), and every temporary exception is rechecked on 2026-10-30. The expiry tests pin the earliest date, and the README no longer copies the exception list. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The plugin calls OpenIapModule.storeId and StoreIds, which first ship in openiap-apple 4.0.0. A floor of 3.6.1 would resolve a 3.x release that does not compile. The parity audit pins the new floor. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The release card gets a Breaking changes list that names the affected packages and the action to take, and the migration guide gets a Provider contract upgrade section with the details. The API, error and KMP pages agree with them. The release-note audit pins each item, and the process docs now say that a feature PR may set the Client Protocol version, run scripts/sync-release-generated.sh, and release it with version=current. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The React Native lock reaches image-size only through Metro 0.84.4, and Metro 0.84.5 drops it, so a Metro bump clears both advisories. The Expo example reaches it only through a nested Metro 0.76.9 under stale peer resolutions. The policy wording now covers an advisory the lock does not clear yet. Two audit tests no longer crash without the root exception file or match "11 dependency audit findings" for "1". Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The cancellation, Godot error-code and Android error-code notes now name the exact operations and packages that changed. Flutter's subscription-check message change is documented. A feature PR that sets the Client Protocol version also refreshes bun.lock before running the sync script. The release note audit masks version numbers, so a post-release version correction does not fail CI. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The React Native lock reaches image-size through Metro 0.84.4, pinned by @expo/metro 56.0.0 and resolved for the community CLI plugin. Re-resolving Metro inside the locked range clears both advisories. The policy now says an exception may also cover a clearing bump that has not been tested yet. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The Godot Apple error-code note now names what changed (get_storefront, products_fetched failure payloads and the iOS-only calls) and what they carried before. Flutter's hasActiveSubscriptions no longer checks init in Dart, which the guide now says. AGENTS.md and the sync-script comment match the lockfile refresh step. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
CodeQL flagged the single-pass tag regex as incomplete multi-character sanitization. A depth counter drops nested or partial tags instead. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Apple and Android stores now share one provider contract in the native packages and the six SDKs. An app links a compatible provider, selects it and rebuilds. Purchase APIs stay the same, and Play, Horizon, Amazon, StoreKit and every legacy flag keep working.
Identity. Client Protocol 0.2.0 adds a required
storeIdto every output that carriesIapStore. The enum is frozen: a new store reportsunknownplus its own id, and an adapter for an existing store keeps the canonical id.Android.
openiap-coreholds the contract and the Play, Horizon and Amazon artifacts depend on it. A provider is found through thedev.hyo.openiap.PROVIDERmanifest key and selected withopeniapStoreandopeniapProvider(Expo, Godot and MAUI have equivalents). A flavored app can keep aproviderflavor beside its store flavors.Apple.
OpenIapModulekeeps its API and selectors. StoreKit sits behind a provider chosen from Info.plist, and a bad selection is a developer error, never a silent fallback.New. Kotlin (
openiap-conformance) and Swift (OpenIapConformance) conformance suites, an optional store registry, a provider guide, and a community Amazon example. The example is educational; FireOS apps should use the official integration.Breaking changes. The release card lists 14, each with the action to take, and the upgrade guide has the details. The main ones:
storeIdis required on hand-built purchases and IAPKit results, KMP'sStoregainsUNKNOWN, Kotlin purchase constructors andcopychange, Apple needs tvOS 16, and error codes, Horizon restore events and iOS billing-grace checks change in some SDKs.Release train (card included, written as published): Apple and Google 4.0.0, React Native 17.0.0, Expo 6.0.0, Flutter 11.0.0, Godot 4.0.0, KMP 4.0.0, MAUI 3.0.0, Client Protocol 0.2.0, CLI 0.2.0. Client Protocol 0.2.0 is already set in
specs/client/package.jsonbecause the provider compatibility checks read it, so release it withversion=current;minorwould publish 0.3.0.Verified. CI passed at
c751be8b(76 checks). On real devices atc751be8b, the native example and all six SDKs completed a sandbox purchase, local IAPKit verification and finish on Google Play (Pixel) and Amazon (Fire tablet, App Tester). On Horizon (Quest 3) all seven connect, load products and read owned purchases; Flutter and Godot restore behave as documented. Horizon checkout costs real money, so no Horizon purchase was made, and Vega only builds and launches. On iPhone atc751be8b,swift testpasses (180 tests), every example connects and loads products, and the Flutter plugin compiles against this PR's Apple package. New iOS sandbox purchases were last run at63b54bc0and are pending. The community example passes its 16 conformance behaviors and Fire-tablet App Tester flows at412b86e3.Also in this branch. Security work that is not provider work:
bracesstays on upstream with an expiring OSV exception (no upstream fix for GHSA-vfj7-8cjw-p6xm), the node-forge and image-size exceptions run to 2026-10-30, eight advisories published after the last green run are fixed in the locks (security notes), and the Flutter SwiftPM floor isopeniap-apple4.0.0. The Codecov step and coverage gate are rewritten. Rootpackage.jsonandbun.lockchanged, so merging deploys Kit to production.Known limits. Native conformance does not certify server lifecycle behavior. KMP's neutral variant compiles against Play Billing only, which external-provider runtimes exclude. Invalid Godot settings fail dependency resolution because its export hook cannot cancel the export. A module without platform flavors still pins one store per build. The KMP example keeps one client per screen and crashes on Horizon when Available Purchases opens after the purchase flow screen; that code is unchanged by this PR.
Preview
common-provider-expo-public.mp4
provider-architecture-amazon-example.mp4
Earlier Fire label preview. Sampled Fire home and package usage guide.
Sampled browser previews: provider setup, nullable renewal, SDK configuration, verification errors, Apple lifecycle/authoring and the existing Expo app installation recipe.
provider-generic-vendors-docs-preview.mp4
provider-errors-and-setup.mp4
apple-provider-review.mp4
expo-community-guide-final.mp4